home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / tcpin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  24.6 KB  |  907 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  *
  6.  * Mods by PA0GRI (access control)
  7.  * Copyright 1992 Gerard J van der Grinten, PA0GRI
  8.  */
  9. #include "global.h"
  10. #include "config.h"
  11. #include "timer.h"
  12. #include "mbuf.h"
  13. #include "netuser.h"
  14. #include "internet.h"
  15. #include "tcp.h"
  16. #include "icmp.h"
  17. #include "iface.h"
  18. #include "ip.h"
  19.  
  20. static void update __ARGS((struct tcb *tcb,struct tcp *seg,int16 length));
  21. static void proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  22. static void add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  23.     struct mbuf *bp,int16 length));
  24. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  25.     struct mbuf **bp,int16 *length));
  26. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  27.     int16 *length));
  28. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  29.  
  30. /* This function is called from IP with the IP header in machine byte order,
  31.  * along with a mbuf chain pointing to the TCP header.
  32.  */
  33. void
  34. tcp_input(iface,ip,bp,rxbroadcast)
  35. struct iface *iface;    /* Incoming interface (ignored) */
  36. struct mbuf *bp;    /* Data field, if any */
  37. struct ip *ip;        /* IP header */
  38. int rxbroadcast;    /* Incoming broadcast - discard if true */
  39. {
  40.     struct tcb *ntcb;
  41.     register struct tcb *tcb;    /* TCP Protocol control block */
  42.     struct tcp seg;            /* Local copy of segment header */
  43.     struct connection conn;        /* Local copy of addresses */
  44.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  45.     int hdrlen;            /* Length of TCP header */
  46.     int16 length;
  47.  
  48.     if(bp == NULLBUF)
  49.         return;
  50.  
  51.     tcpInSegs++;
  52.     if(rxbroadcast){
  53.         /* Any TCP packet arriving as a broadcast is
  54.          * to be completely IGNORED!!
  55.          */
  56.         free_p(bp);
  57.         return;
  58.     }
  59.     length = ip->length - IPLEN - ip->optlen;
  60.     ph.source = ip->source;
  61.     ph.dest = ip->dest;
  62.     ph.protocol = ip->protocol;
  63.     ph.length = length;
  64.     if(cksum(&ph,bp,length) != 0){
  65.         /* Checksum failed, ignore segment completely */
  66.         tcpInErrs++;
  67.         free_p(bp);
  68.         return;
  69.     }
  70.     /* Form local copy of TCP header in host byte order */
  71.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  72.         /* TCP header is too small */
  73.         free_p(bp);
  74.         return;
  75.     }
  76.     length -= hdrlen;
  77.  
  78.     /* Fill in connection structure and find TCB */
  79.     conn.local.address = ip->dest;
  80.     conn.local.port = seg.dest;
  81.     conn.remote.address = ip->source;
  82.     conn.remote.port = seg.source;
  83.     
  84.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  85.         /* If memory low, reject it - WG7J */
  86.         /* If this segment doesn't carry a SYN, reject it */
  87.         if((availmem() < Memthresh) || !seg.flags.syn){
  88.             free_p(bp);
  89.             reset(ip,&seg);
  90.             return;
  91.         }
  92. #ifdef  TCPACCESS
  93.         if(tcp_check(TCPaccess,ip->source,seg.dest) != 0 ) {
  94.             free_p(bp);
  95.             reset(ip,&seg);
  96.             return;
  97.         }
  98. #endif
  99.         /* See if there's a TCP_LISTEN on this socket with
  100.          * unspecified remote address and port
  101.          */
  102.         conn.remote.address = 0;
  103.         conn.remote.port = 0;
  104.         /* NOS currently always listens on unspecified addresses ! - WG7J */
  105.         conn.local.address = 0;
  106.         if((tcb = lookup_tcb(&conn)) == NULLTCB){
  107. #ifdef notdef
  108.             /* Nope, try unspecified local address too */
  109.             conn.local.address = 0;
  110.             if((tcb = lookup_tcb(&conn)) == NULLTCB){
  111. #endif
  112.                 /* No LISTENs, so reject */
  113.                 free_p(bp);
  114.                 reset(ip,&seg);
  115.                 return;
  116. #ifdef notdef
  117.             }
  118. #endif
  119.         }
  120.         /* We've found an server listen socket, so clone the TCB */
  121.         if(tcb->flags.clone){
  122.             ntcb = (struct tcb *)mallocw(sizeof (struct tcb));
  123.             ASSIGN(*ntcb,*tcb);
  124.             tcb = ntcb;
  125.             tcb->timer.arg = tcb;
  126.             /* Put on list */
  127.             tcb->next = Tcbs;
  128.             Tcbs = tcb;
  129.         }
  130.         /* Put all the socket info into the TCB */
  131.         tcb->conn.local.address = ip->dest;
  132.         tcb->conn.remote.address = ip->source;
  133.         tcb->conn.remote.port = seg.source;
  134.     }
  135.     tcb->flags.congest = ip->flags.congest;
  136.     /* Do unsynchronized-state processing (p. 65-68) */
  137.     switch(tcb->state){
  138.     case TCP_CLOSED:
  139.         free_p(bp);
  140.         reset(ip,&seg);
  141.         return;
  142.     case TCP_LISTEN:
  143.         if(seg.flags.rst){
  144.             free_p(bp);
  145.             return;
  146.         }
  147.         if(seg.flags.ack){
  148.             free_p(bp);
  149.             reset(ip,&seg);
  150.             return;
  151.         }
  152.         if(seg.flags.syn){
  153.             /* (Security check is bypassed) */
  154.             /* page 66 */
  155.             proc_syn(tcb,ip->tos,&seg);
  156.             send_syn(tcb);
  157.             setstate(tcb,TCP_SYN_RECEIVED);        
  158.             if(length != 0 || seg.flags.fin) {
  159.                 /* Continue processing if there's more */
  160.                 break;
  161.             }
  162.             tcp_output(tcb);
  163.         }
  164.         free_p(bp);    /* Unlikely to get here directly */
  165.         return;
  166.     case TCP_SYN_SENT:
  167.         if(seg.flags.ack){
  168.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  169.                 free_p(bp);
  170.                 reset(ip,&seg);
  171.                 return;
  172.             }
  173.         }
  174.         if(seg.flags.rst){    /* p 67 */
  175.             if(seg.flags.ack){
  176.                 /* The ack must be acceptable since we just checked it.
  177.                  * This is how the remote side refuses connect requests.
  178.                  */
  179.                 close_self(tcb,RESET);
  180.             }
  181.             free_p(bp);
  182.             return;
  183.         }
  184.         /* (Security check skipped here) */
  185.         /* Check incoming precedence; it must match if there's an ACK */
  186.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  187.             free_p(bp);
  188.             reset(ip,&seg);
  189.             return;
  190.         }
  191.         if(seg.flags.syn){
  192.             proc_syn(tcb,ip->tos,&seg);
  193.             if(seg.flags.ack){
  194.                 /* Our SYN has been acked, otherwise the ACK
  195.                  * wouldn't have been valid.
  196.                  */
  197.                 update(tcb,&seg,length);
  198.                 setstate(tcb,TCP_ESTABLISHED);
  199.             } else {
  200.                 setstate(tcb,TCP_SYN_RECEIVED);
  201.             }
  202.             if(length != 0 || seg.flags.fin) {
  203.                 break;        /* Continue processing if there's more */
  204.             }
  205.             tcp_output(tcb);
  206.         } else {
  207.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  208.         }
  209.         return;
  210.     }
  211.     /* We reach this point directly in any synchronized state. Note that
  212.      * if we fell through from LISTEN or SYN_SENT processing because of a
  213.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  214.      */
  215.  
  216.     /* Trim segment to fit receive window. */
  217.     if(trim(tcb,&seg,&bp,&length) == -1){
  218.         /* Segment is unacceptable */
  219.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  220.             /* In SYN_RECEIVED state, answer a retransmitted SYN 
  221.              * with a retransmitted SYN/ACK.
  222.              */
  223.             if(tcb->state == TCP_SYN_RECEIVED)
  224.                 tcb->snd.ptr = tcb->snd.una;
  225.             tcb->flags.force = 1;
  226.             tcp_output(tcb);
  227.         }
  228.         return;
  229.     }
  230.     /* If segment isn't the next one expected, and there's data
  231.      * or flags associated with it, put it on the resequencing
  232.      * queue, ACK it and return.
  233.      *
  234.      * Processing the ACK in an out-of-sequence segment without
  235.      * flags or data should be safe, however.
  236.      */
  237.     if(seg.seq != tcb->rcv.nxt
  238.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  239.         add_reseq(tcb,ip->tos,&seg,bp,length);
  240.         tcb->flags.force = 1;
  241.         tcp_output(tcb);
  242.         return;
  243.     }
  244.     /* This loop first processes the current segment, and then
  245.      * repeats if it can process the resequencing queue.
  246.      */
  247.     for(;;){
  248.         /* We reach this point with an acceptable segment; all data and flags
  249.          * are in the window, and the starting sequence number equals rcv.nxt
  250.          * (p. 70)
  251.          */    
  252.         if(seg.flags.rst){
  253.             if(tcb->state == TCP_SYN_RECEIVED
  254.              && !tcb->flags.clone && !tcb->flags.active){
  255.                 /* Go back to listen state only if this was
  256.                  * not a cloned or active server TCB
  257.                  */
  258.                 setstate(tcb,TCP_LISTEN);
  259.             } else {
  260.                 close_self(tcb,RESET);
  261.             }
  262.             free_p(bp);
  263.             return;
  264.         }
  265.         /* (Security check skipped here) p. 71 */
  266.         /* Check for precedence mismatch or erroneous extra SYN */
  267.         if(PREC(ip->tos) != PREC(tcb->tos) || seg.flags.syn){
  268.             free_p(bp);
  269.             reset(ip,&seg);
  270.             return;
  271.         }
  272.         /* Check ack field p. 72 */
  273.         if(!seg.flags.ack){
  274.             free_p(bp);    /* All segments after synchronization must have ACK */
  275.             return;
  276.         }
  277.         /* Process ACK */
  278.         switch(tcb->state){
  279.         case TCP_SYN_RECEIVED:
  280.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  281.                 update(tcb,&seg,length);
  282.                 setstate(tcb,TCP_ESTABLISHED);
  283.             } else {
  284.                 free_p(bp);
  285.                 reset(ip,&seg);
  286.                 return;
  287.             }
  288.             break;
  289.         case TCP_ESTABLISHED:
  290.         case TCP_CLOSE_WAIT:
  291.             update(tcb,&seg,length);
  292.             break;
  293.         case TCP_FINWAIT1:    /* p. 73 */
  294.             update(tcb,&seg,length);
  295.             if(tcb->sndcnt == 0){
  296.                 /* Our FIN is acknowledged */
  297.                 setstate(tcb,TCP_FINWAIT2);
  298.             }
  299.             break;
  300.         case TCP_FINWAIT2:
  301.             update(tcb,&seg,length);
  302.             break;
  303.         case TCP_CLOSING:
  304.             update(tcb,&seg,length);
  305.             if(tcb->sndcnt == 0){
  306.                 /* Our FIN is acknowledged */
  307.                 setstate(tcb,TCP_TIME_WAIT);
  308.                 set_timer(&tcb->timer,MSL2*1000L);
  309.                 start_timer(&tcb->timer);
  310.             }
  311.             break;
  312.         case TCP_LAST_ACK:
  313.             update(tcb,&seg,length);
  314.             if(tcb->sndcnt == 0){
  315.                 /* Our FIN is acknowledged, close connection */
  316.                 close_self(tcb,NORMAL);
  317.                 return;
  318.             }            
  319.             break;
  320.         case TCP_TIME_WAIT:
  321.             start_timer(&tcb->timer);
  322.             break;
  323.         }
  324.  
  325.         /* (URGent bit processing skipped here) */
  326.  
  327.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  328.         if(length != 0){
  329.             switch(tcb->state){
  330.             case TCP_SYN_RECEIVED:
  331.             case TCP_ESTABLISHED:
  332.             case TCP_FINWAIT1:
  333.             case TCP_FINWAIT2:
  334.                 /* Place on receive queue */
  335.                 append(&tcb->rcvq,bp);
  336.                 tcb->rcvcnt += length;
  337.                 tcb->rcv.nxt += length;
  338.                 tcb->rcv.wnd -= length;
  339.                 tcb->flags.force = 1;
  340.                 /* Notify user */
  341.                 if(tcb->r_upcall)
  342.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  343.                 break;
  344.             default:
  345.                 /* Ignore segment text */
  346.                 free_p(bp);
  347.                 break;
  348.             }
  349.         }
  350.         /* process FIN bit (p 75) */
  351.         if(seg.flags.fin){
  352.             tcb->flags.force = 1;    /* Always respond with an ACK */
  353.  
  354.             switch(tcb->state){
  355.             case TCP_SYN_RECEIVED:
  356.             case TCP_ESTABLISHED:
  357.                 tcb->rcv.nxt++;
  358.                 setstate(tcb,TCP_CLOSE_WAIT);
  359.                 break;
  360.             case TCP_FINWAIT1:
  361.                 tcb->rcv.nxt++;
  362.                 if(tcb->sndcnt == 0){
  363.                     /* Our FIN has been acked; bypass TCP_CLOSING state */
  364.                     setstate(tcb,TCP_TIME_WAIT);
  365.                     set_timer(&tcb->timer,MSL2*1000L);
  366.                     start_timer(&tcb->timer);
  367.                 } else {
  368.                     setstate(tcb,TCP_CLOSING);
  369.                 }
  370.                 break;
  371.             case TCP_FINWAIT2:
  372.                 tcb->rcv.nxt++;
  373.                 setstate(tcb,TCP_TIME_WAIT);
  374.                 set_timer(&tcb->timer,MSL2*1000L);
  375.                 start_timer(&tcb->timer);
  376.                 break;
  377.             case TCP_CLOSE_WAIT:
  378.             case TCP_CLOSING:
  379.             case TCP_LAST_ACK:
  380.                 break;        /* Ignore */
  381.             case TCP_TIME_WAIT:    /* p 76 */
  382.                 start_timer(&tcb->timer);
  383.                 break;
  384.             }
  385.             /* Call the client again so he can see EOF */
  386.             if(tcb->r_upcall)
  387.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  388.         }
  389.         /* Scan the resequencing queue, looking for a segment we can handle,
  390.          * and freeing all those that are now obsolete.
  391.          */
  392.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  393.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  394.             if(trim(tcb,&seg,&bp,&length) == 0)
  395.                 goto gotone;
  396.             /* Segment is an old one; trim has freed it */
  397.         }
  398.         break;
  399. gotone:    ;
  400.     }
  401.     tcp_output(tcb);    /* Send any necessary ack */
  402. }
  403.  
  404. /* Process an incoming ICMP response */
  405. void
  406. tcp_icmp(icsource,source,dest,type,code,bpp)
  407. int32 icsource;            /* Sender of ICMP message (not used) */
  408. int32 source;            /* Original IP datagram source (i.e. us) */
  409. int32 dest;            /* Original IP datagram dest (i.e., them) */
  410. char type,code;            /* ICMP error codes */
  411. struct mbuf **bpp;        /* First 8 bytes of TCP header */
  412. {
  413.     struct tcp seg;
  414.     struct connection conn;
  415.     register struct tcb *tcb;
  416.  
  417.     /* Extract the socket info from the returned TCP header fragment
  418.      * Note that since this is a datagram we sent, the source fields
  419.      * refer to the local side.
  420.      */
  421.     ntohtcp(&seg,bpp);
  422.     conn.local.port = seg.source;
  423.     conn.remote.port = seg.dest;
  424.     conn.local.address = source;
  425.     conn.remote.address = dest;
  426.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  427.         return;    /* Unknown connection, ignore */
  428.  
  429.     /* Verify that the sequence number in the returned segment corresponds
  430.      * to something currently unacknowledged. If not, it can safely
  431.      * be ignored.
  432.      */
  433.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  434.         return;
  435.  
  436.     /* Destination Unreachable and Time Exceeded messages never kill a
  437.      * connection; the info is merely saved for future reference.
  438.      */
  439.     switch(uchar(type)){
  440.     case ICMP_DEST_UNREACH:
  441.     case ICMP_TIME_EXCEED:
  442.         tcb->type = type;
  443.         tcb->code = code;
  444.         break;
  445.     case ICMP_QUENCH:
  446.         /* Source quench; cut the congestion window in half,
  447.          * but don't let it go below one packet
  448.          */
  449.         tcb->cwind /= 2;
  450.         tcb->cwind = max(tcb->mss,tcb->cwind);
  451.         break;
  452.     }
  453. }
  454. /* Send an acceptable reset (RST) response for this segment
  455.  * The RST reply is composed in place on the input segment
  456.  */
  457. void
  458. reset(ip,seg)
  459. struct ip *ip;            /* Offending IP header */
  460. register struct tcp *seg;    /* Offending TCP header */
  461. {
  462.     struct mbuf *hbp;
  463.     struct pseudo_header ph;
  464.     int16 tmp;
  465.  
  466.     if(seg->flags.rst)
  467.         return;    /* Never send an RST in response to an RST */
  468.  
  469.     /* Compose the RST IP pseudo-header, swapping addresses */
  470.     ph.source = ip->dest;
  471.     ph.dest = ip->source;
  472.     ph.protocol = TCP_PTCL;
  473.     ph.length = TCPLEN;
  474.  
  475.     /* Swap port numbers */
  476.     tmp = seg->source;
  477.     seg->source = seg->dest;
  478.     seg->dest = tmp;
  479.  
  480.     if(seg->flags.ack){
  481.         /* This reset is being sent to clear a half-open connection.
  482.          * Set the sequence number of the RST to the incoming ACK
  483.          * so it will be acceptable.
  484.          */
  485.         seg->flags.ack = 0;
  486.         seg->seq = seg->ack;
  487.         seg->ack = 0;
  488.     } else {
  489.         /* We're rejecting a connect request (SYN) from TCP_LISTEN state
  490.          * so we have to "acknowledge" their SYN.
  491.          */
  492.         seg->flags.ack = 1;
  493.         seg->ack = seg->seq;
  494.         seg->seq = 0;
  495.         if(seg->flags.syn)
  496.             seg->ack++;
  497.     }
  498.     /* Set remaining parts of packet */
  499.     seg->flags.urg = 0;
  500.     seg->flags.psh = 0;
  501.     seg->flags.rst = 1;
  502.     seg->flags.syn = 0;
  503.     seg->flags.fin = 0;
  504.     seg->wnd = 0;
  505.     seg->up = 0;
  506.     seg->mss = 0;
  507.     seg->optlen = 0;
  508.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  509.         return;
  510.     /* Ship it out (note swap of addresses) */
  511.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  512.     tcpOutRsts++;
  513. }
  514.  
  515. /* Process an incoming acknowledgement and window indication.
  516.  * From page 72.
  517.  */
  518. static void
  519. update(tcb,seg,length)
  520. register struct tcb *tcb;
  521. register struct tcp *seg;
  522. int16 length;
  523. {
  524.     int16 acked;
  525.     int16 expand;
  526.  
  527.     acked = 0;
  528.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  529.         tcb->flags.force = 1;    /* Acks something not yet sent */
  530.         return;
  531.     }
  532.     /* Decide if we need to do a window update.
  533.      * This is always checked whenever a legal ACK is received,
  534.      * even if it doesn't actually acknowledge anything,
  535.      * because it might be a spontaneous window reopening.
  536.      */
  537.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  538.      && seq_ge(seg->ack,tcb->snd.wl2))){
  539.         /* If the window had been closed, crank back the
  540.          * send pointer so we'll immediately resume transmission.
  541.          * Otherwise we'd have to wait until the next probe.
  542.          */
  543.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  544.             tcb->snd.ptr = tcb->snd.una;
  545.         tcb->snd.wnd = seg->wnd;
  546.         tcb->snd.wl1 = seg->seq;
  547.         tcb->snd.wl2 = seg->ack;
  548.     }
  549.     /* See if anything new is being acknowledged */
  550.     if(!seq_gt(seg->ack,tcb->snd.una)){
  551.         if(seg->ack != tcb->snd.una)
  552.             return;    /* Old ack, ignore */
  553.  
  554.         if(length != 0 || seg->flags.syn || seg->flags.fin)
  555.             return;    /* Nothing acked, but there is data */
  556.  
  557.         /* Van Jacobson "fast recovery" code */
  558.         if(++tcb->dupacks == TCPDUPACKS){
  559.             /* We've had a burst of do-nothing acks, so
  560.              * we almost certainly lost a packet.
  561.              * Resend it now to avoid a timeout. (This is
  562.              * Van Jacobson's 'quick recovery' algorithm.)
  563.              */
  564.             int32 ptrsave;
  565.  
  566.             /* Knock the threshold down just as though
  567.              * this were a timeout, since we've had
  568.              * network congestion.
  569.              */
  570.             tcb->ssthresh = tcb->cwind/2;
  571.             tcb->ssthresh = max(tcb->ssthresh,tcb->mss);
  572.  
  573.             /* Manipulate the machinery in tcp_output() to
  574.              * retransmit just the missing packet
  575.              */
  576.             ptrsave = tcb->snd.ptr;
  577.             tcb->snd.ptr = tcb->snd.una;
  578.             tcb->cwind = tcb->mss;
  579.             tcp_output(tcb);
  580.             tcb->snd.ptr = ptrsave;
  581.  
  582.             /* "Inflate" the congestion window, pretending as
  583.              * though the duplicate acks were normally acking
  584.              * the packets beyond the one that was lost.
  585.              */
  586.             tcb->cwind = tcb->ssthresh + TCPDUPACKS*tcb->mss;
  587.         } else if(tcb->dupacks > TCPDUPACKS){
  588.             /* Continue to inflate the congestion window
  589.              * until the acks finally get "unstuck".
  590.              */
  591.             tcb->cwind += tcb->mss;
  592.         }
  593.         return;
  594.     }
  595.     if(tcb->dupacks >= TCPDUPACKS && tcb->cwind > tcb->ssthresh){
  596.         /* The acks have finally gotten "unstuck". So now we
  597.          * can "deflate" the congestion window, i.e. take it
  598.          * back down to where it would be after slow start
  599.          * finishes.
  600.          */
  601.         tcb->cwind = tcb->ssthresh;
  602.     }
  603.     tcb->dupacks = 0;
  604.  
  605.     /* We're here, so the ACK must have actually acked something */
  606.     acked = seg->ack - tcb->snd.una;
  607.  
  608.     /* Expand congestion window if not already at limit and if
  609.      * this packet wasn't retransmitted
  610.      */
  611.     if(tcb->cwind < tcb->snd.wnd && !tcb->flags.retran){
  612.         if(tcb->cwind < tcb->ssthresh){
  613.             /* Still doing slow start/CUTE, expand by amount acked */
  614.             expand = min(acked,tcb->mss);
  615.         } else {
  616.             /* Steady-state test of extra path capacity */
  617.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  618.         }
  619.         /* Guard against arithmetic overflow */
  620.         if(tcb->cwind + expand < tcb->cwind)
  621.             expand = MAXINT16 - tcb->cwind;
  622.  
  623.         /* Don't expand beyond the offered window */
  624.         if(tcb->cwind + expand > tcb->snd.wnd)
  625.             expand = tcb->snd.wnd - tcb->cwind;
  626.  
  627.         if(expand != 0){
  628. #ifdef    notdef
  629.             /* Kick up the mean deviation estimate to prevent
  630.              * unnecessary retransmission should we already be
  631.              * bandwidth limited
  632.              */
  633.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  634. #endif
  635.             tcb->cwind += expand;
  636.         }
  637.     }
  638.     /* Round trip time estimation */
  639.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  640.         /* A timed sequence number has been acked */
  641.         tcb->flags.rtt_run = 0;
  642.         if(!(tcb->flags.retran)){
  643.             int32 rtt;    /* measured round trip time */
  644.             int32 abserr;    /* abs(rtt - srtt) */
  645.  
  646.             /* This packet was sent only once and now
  647.              * it's been acked, so process the round trip time
  648.              */
  649.             rtt = msclock() - tcb->rtt_time;
  650.  
  651.             abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  652.             /* Run SRTT and MDEV integrators, with rounding */
  653.             tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  654.             tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  655.  
  656.             rtt_add(tcb->conn.remote.address,rtt);
  657.             /* Reset the backoff level */
  658.             tcb->backoff = 0;
  659.         }
  660.     }
  661.     tcb->sndcnt -= acked;    /* Update virtual byte count on snd queue */
  662.     tcb->snd.una = seg->ack;
  663.  
  664.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  665.     if(!(tcb->flags.synack)){
  666.         tcb->flags.synack = 1;
  667.         acked--;    /* One less byte to pull from real snd queue */
  668.     }
  669.     /* Remove acknowledged bytes from the send queue and update the
  670.      * unacknowledged pointer. If a FIN is being acked,
  671.      * pullup won't be able to remove it from the queue, but that
  672.      * causes no harm.
  673.      */
  674.     pullup(&tcb->sndq,NULLCHAR,acked);
  675.  
  676.     /* Stop retransmission timer, but restart it if there is still
  677.      * unacknowledged data. If there is no more unacked data,
  678.      * the transmitter has gone at least momentarily idle, so
  679.      * record the time for the VJ restart-slowstart rule.
  680.      */    
  681.     stop_timer(&tcb->timer);
  682.     if(tcb->snd.una != tcb->snd.nxt)
  683.         start_timer(&tcb->timer);
  684.     else
  685.         tcb->lastactive = msclock();
  686.  
  687.     /* If retransmissions have been occurring, make sure the
  688.      * send pointer doesn't repeat ancient history
  689.      */
  690.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  691.         tcb->snd.ptr = tcb->snd.una;
  692.  
  693.     /* Clear the retransmission flag since the oldest
  694.      * unacknowledged segment (the only one that is ever retransmitted)
  695.      * has now been acked.
  696.      */
  697.     tcb->flags.retran = 0;
  698.  
  699.     /* If outgoing data was acked, notify the user so he can send more
  700.      * unless we've already sent a FIN.
  701.      */
  702.     if(acked != 0 && tcb->t_upcall
  703.      && (tcb->state == TCP_ESTABLISHED || tcb->state == TCP_CLOSE_WAIT)){
  704.         (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  705.     }
  706. }
  707.  
  708. /* Determine if the given sequence number is in our receiver window.
  709.  * NB: must not be used when window is closed!
  710.  */
  711. static
  712. int
  713. in_window(tcb,seq)
  714. struct tcb *tcb;
  715. int32 seq;
  716. {
  717.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  718. }
  719.  
  720. /* Process an incoming SYN */
  721. static void
  722. proc_syn(tcb,tos,seg)
  723. register struct tcb *tcb;
  724. char tos;
  725. struct tcp *seg;
  726. {
  727.     int16 mtu;
  728.     struct tcp_rtt *tp;
  729.  
  730.     tcb->flags.force = 1;    /* Always send a response */
  731.  
  732.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  733.      * SND.WND are initialized here since it's possible for the
  734.      * window update routine in update() to fail depending on the
  735.      * IRS if they are left unitialized.
  736.      */
  737.     /* Check incoming precedence and increase if higher */
  738.     if(PREC(tos) > PREC(tcb->tos))
  739.         tcb->tos = tos;
  740.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  741.     tcb->snd.wl1 = tcb->irs = seg->seq;
  742.     tcb->snd.wnd = seg->wnd;
  743.     if(seg->mss != 0)
  744.         tcb->mss = seg->mss;
  745.     /* Check the MTU of the interface we'll use to reach this guy
  746.      * and lower the MSS so that unnecessary fragmentation won't occur
  747.      */
  748.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  749.         /* Allow space for the TCP and IP headers */
  750.         mtu -= TCPLEN + IPLEN;
  751.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  752.     }
  753.     /* See if there's round-trip time experience */
  754.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  755.         tcb->srtt = tp->srtt;
  756.         tcb->mdev = tp->mdev;
  757.     }
  758. }
  759.  
  760. /* Generate an initial sequence number and put a SYN on the send queue */
  761. void
  762. send_syn(tcb)
  763. register struct tcb *tcb;
  764. {
  765.     tcb->iss = geniss();
  766.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  767.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  768.     tcb->sndcnt++;
  769.     tcb->flags.force = 1;
  770. }
  771.  
  772. /* Add an entry to the resequencing queue in the proper place */
  773. static void
  774. add_reseq(tcb,tos,seg,bp,length)
  775. struct tcb *tcb;
  776. char tos;
  777. struct tcp *seg;
  778. struct mbuf *bp;
  779. int16 length;
  780. {
  781.     register struct reseq *rp,*rp1;
  782.  
  783.     /* Allocate reassembly descriptor */
  784.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  785.         /* No space, toss on floor */
  786.         free_p(bp);
  787.         return;
  788.     }
  789.     ASSIGN(rp->seg,*seg);
  790.     rp->tos = tos;
  791.     rp->bp = bp;
  792.     rp->length = length;
  793.  
  794.     /* Place on reassembly list sorting by starting seq number */
  795.     rp1 = tcb->reseq;
  796.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  797.         /* Either the list is empty, or we're less than all other
  798.          * entries; insert at beginning.
  799.          */
  800.         rp->next = rp1;
  801.         tcb->reseq = rp;
  802.     } else {
  803.         /* Find the last entry less than us */
  804.         for(;;){
  805.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  806.                 /* We belong just after this one */
  807.                 rp->next = rp1->next;
  808.                 rp1->next = rp;
  809.                 break;
  810.             }
  811.             rp1 = rp1->next;
  812.         }
  813.     }
  814. }
  815.  
  816. /* Fetch the first entry off the resequencing queue */
  817. static void
  818. get_reseq(tcb,tos,seg,bp,length)
  819. register struct tcb *tcb;
  820. char *tos;
  821. struct tcp *seg;
  822. struct mbuf **bp;
  823. int16 *length;
  824. {
  825.     register struct reseq *rp;
  826.  
  827.     if((rp = tcb->reseq) == NULLRESEQ)
  828.         return;
  829.  
  830.     tcb->reseq = rp->next;
  831.  
  832.     *tos = rp->tos;
  833.     ASSIGN(*seg,rp->seg);
  834.     *bp = rp->bp;
  835.     *length = rp->length;
  836.     free((char *)rp);
  837. }
  838.  
  839. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  840.  * unacceptable.
  841.  */
  842. static int
  843. trim(tcb,seg,bpp,length)
  844. register struct tcb *tcb;
  845. register struct tcp *seg;
  846. struct mbuf **bpp;
  847. int16 *length;
  848. {
  849.     long dupcnt,excess;
  850.     int16 len;        /* Segment length including flags */
  851.     char accept = 0;
  852.  
  853.     len = *length;
  854.     if(seg->flags.syn)
  855.         len++;
  856.     if(seg->flags.fin)
  857.         len++;
  858.  
  859.     /* Acceptability tests */
  860.     if(tcb->rcv.wnd == 0){
  861.         /* Only in-order, zero-length segments are acceptable when
  862.          * our window is closed.
  863.          */
  864.         if(seg->seq == tcb->rcv.nxt && len == 0){
  865.             return 0;    /* Acceptable, no trimming needed */
  866.         }
  867.     } else {
  868.         /* Some part of the segment must be in the window */
  869.         if(in_window(tcb,seg->seq)){
  870.             accept++;    /* Beginning is */
  871.         } else if(len != 0){
  872.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  873.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  874.                 accept++;
  875.             }
  876.         }
  877.     }
  878.     if(!accept){
  879.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  880.         free_p(*bpp);
  881.         return -1;
  882.     }
  883.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  884.         tcb->rerecv += dupcnt;
  885.         /* Trim off SYN if present */
  886.         if(seg->flags.syn){
  887.             /* SYN is before first data byte */
  888.             seg->flags.syn = 0;
  889.             seg->seq++;
  890.             dupcnt--;
  891.         }
  892.         if(dupcnt > 0){
  893.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  894.             seg->seq += dupcnt;
  895.             *length -= dupcnt;
  896.         }
  897.     }
  898.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  899.         tcb->rerecv += excess;
  900.         /* Trim right edge */
  901.         *length -= excess;
  902.         trim_mbuf(bpp,*length);
  903.         seg->flags.fin = 0;    /* FIN follows last data byte */
  904.     }
  905.     return 0;
  906. }
  907.